﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using GameView.Comment;
using GameView.Services;
using GameView.Services.Comment;
using GameView.Services.Dtos;
using GameView.Services.Dtos.Project;
using GameView.Services.Dtos.WithdrawalDto;
using System.Collections.ObjectModel;
using System.ComponentModel.DataAnnotations;
using System.Windows.Controls;

namespace GameView.ViewModels
{
    public partial class WithdrawalViewModel : ObservableObject
    {
        private Dictionary<string, int> OrderStatusDic = new()
        {
            ["全部"] = 0,
            ["待付款"] = 2001,
            ["账号错误"] = 2002,
            ["已付款"] = 2003,
            ["已屏蔽"] = 2004,
            ["待审核"] = 2005
        };

        private readonly WithdrawalService _service;
        private readonly ProjectService _proService;

        private readonly IMessenger _messenger;

        public WithdrawalViewModel(WithdrawalService service, ProjectService proService, IMessenger messenger)
        {
            _messenger = messenger;
            _proService = proService;
            _service = service;
            StatusOptions = new(OrderStatusDic.Keys);
            IsMerchant = StaticValues.LoginInfo.PersonInfo.RoleId != 3;
            LoadData().ConfigureAwait(false);
        }

        private List<ProjectWithGamesInfo> pgs = [];

        [ObservableProperty]
        private bool _isLoading = false;

        [ObservableProperty]
        private int _pageIndex = 1;

        [ObservableProperty]
        private int _pageSize = 50;

        [ObservableProperty]
        private int _totalCount = 0;

        [ObservableProperty]
        private int _totalPages = 1;

        [ObservableProperty]
        private bool _hasPrevPages = false;

        [ObservableProperty]
        private bool _hasNextPages = true;

        [ObservableProperty]
        private ObservableCollection<WithdrawalRecords> _rechargeRecords = [];

        [ObservableProperty]
        private WithdrawalRecords? _selectedRow = null;

        [ObservableProperty]
        private bool _isHaveSelected = false;

        [ObservableProperty]
        private int _pageNumber = 1;

        [ObservableProperty]
        private ObservableCollection<string> _statusOptions = [];

        [ObservableProperty]
        private string _selectedStatus;

        [ObservableProperty]
        private ObservableCollection<string> _projectOptions = [];

        [ObservableProperty]
        [NotifyPropertyChangedFor(nameof(GameOptions))]
        private string _selectedProject;

        [ObservableProperty]
        private ObservableCollection<string> _gameOptions = [];

        [ObservableProperty]
        private string _selectedGame;

        [ObservableProperty]
        private bool _isMerchant = false;

        [ObservableProperty]
        private WithdrawalQueryDto _queryDto = new();

        #region st

        [ObservableProperty]
        private long _sTAll = 0;

        [ObservableProperty]
        private long _sT24 = 0;

        [ObservableProperty]
        private long _sTToDay = 0;

        [ObservableProperty]
        private long _sTPage = 0;

        [ObservableProperty]
        private string _sTString = "";

        #endregion st

        [RelayCommand]
        private async Task FirstPage()
        {
            PageIndex = 1;
            PageNumber = 1;
            await LoadFromApi();
        }

        [RelayCommand]
        private async Task PreviousPageAsync()
        {
            PageIndex--;
            PageNumber--;
            await LoadFromApi();
        }

        [RelayCommand]
        private async Task NextPageAsync()
        {
            PageIndex++;
            PageNumber++;
            await LoadFromApi();
        }

        [RelayCommand]
        private void LastPage() => PageIndex = TotalPages;

        [RelayCommand]
        private void SelectionChanged(WithdrawalRecords item)
        {
            IsHaveSelected = false;
            SelectedRow = null;
            if (item == null || item.OrderStatus != 2001)
                return;
            SelectedRow = item;
            IsHaveSelected = true;
        }

        [RelayCommand]
        private async Task ChangePageSize(object size)
        {
            ComboBoxItem cb = (ComboBoxItem)size;
            if (cb.Content is string sizeStr && int.TryParse(sizeStr.Replace("条/页", ""), out var newSize))
            {
                PageSize = newSize;
                PageIndex = 1; // 重置到第一页
                await LoadFromApi();
            }
        }

          partial void OnSelectedProjectChanged(string value)
        {
            // 清空游戏选项
            GameOptions.Clear();

            // 根据选择的项目重新加载游戏选项
            if (!string.IsNullOrEmpty(value))
            {
                var nowProjet = pgs.FirstOrDefault(q => q.Name == SelectedProject);
                if (nowProjet == null || nowProjet.Games.IsNullOrEmpty())
                    return;
                foreach (var game in nowProjet.Games)
                {
                    GameOptions.Add(game.Name);
                }
            }
        }

        [RelayCommand]
        private async Task SearchAsync()
        {
            IsLoading = true;
            await Task.Delay(200);
            try
            {
                if (!SelectedStatus.IsNullOrEmpty() && OrderStatusDic.TryGetValue(SelectedStatus, out var st))
                    QueryDto.OrderStatus = st;
                QueryDto.GameName = SelectedGame;
                var validationResults = QueryDto.Validate(new ValidationContext(QueryDto)).ToList();
                if (validationResults.Any())
                {
                    GlobalMessage.Instance.ShowWarning(string.Join("\n", validationResults.Select(v => v.ErrorMessage)));
                    return;
                }

                PageIndex = 1;
                await LoadFromApi();
            }
            catch (Exception ex)
            {
                GlobalMessage.Instance.ShowError($"数据加载错误：{ex.Message}");
            }
            finally
            { IsLoading = false; }
        }

        [RelayCommand]
        private async Task ConfirmPayment(object record1)
        {
            WithdrawalRecords record = (WithdrawalRecords)record1;
            try
            {
                IsLoading = true;
                var result = await _service.UpdateAsync(new WithdrawalEditDto(record.Id, 2003));
                //if(StaticValues.)
                if (result.StatusCode == 200 && result.Data > 0)
                {
                    record.OrderStatus = 2003;
                    _messenger.Send(new NotificationMsg(new NotificationEntity() { Type = 2003 }, nameof(WithdrawalViewModel)));
                    GlobalMessage.Instance.ShowSuccess("付款确认成功");
                }
                else
                {
                    GlobalMessage.Instance.ShowError($"操作失败: {result.Errors}");
                }
            }
            finally
            {
                IsLoading = false;
            }
        }

        [RelayCommand]
        private async Task AcountError(object record1)
        {
            WithdrawalRecords record = (WithdrawalRecords)record1;
            try
            {
                IsLoading = true;
                var result = await _service.UpdateAsync(new WithdrawalEditDto(record.Id, 2002));
                //if(StaticValues.)
                if (result.StatusCode == 200 && result.Data > 0)
                {
                    record.OrderStatus = 2002;
                    //_messenger.Send(new NotificationMsg(new NotificationEntity() { Type = 2002 }, nameof(WithdrawalViewModel)));
                }
                else
                {
                    GlobalMessage.Instance.ShowError($"操作失败: {result.Errors}");
                }
            }
            finally
            {
                IsLoading = false;
            }
        }

        [RelayCommand]
        private async Task ApplyCheck(object record1)
        {
            WithdrawalRecords record = (WithdrawalRecords)record1;
            try
            {
                IsLoading = true;
                var result = await _service.UpdateAsync(new WithdrawalEditDto(record.Id, 2005));
                //if(StaticValues.)
                if (result.StatusCode == 200 && result.Data > 0)
                {
                    record.OrderStatus = 2005;
                }
                else
                {
                    GlobalMessage.Instance.ShowError($"操作失败: {result.Errors}");
                }
            }
            finally
            {
                IsLoading = false;
            }
        }

        [RelayCommand]
        private async Task LoadData()
        {
            IsLoading = true;
            await Task.Delay(200);
            try
            {
                await LoadFromApi();
                if (StaticValues.LoginInfo.PersonInfo.RoleId != 1)
                {
                    var res = await _proService.GetByPersonIdAsync();
                    pgs = res.Data;
                }
                else
                {
                    var res = await _proService.GetAllAsync();
                    pgs = res.Data;
                }

                ProjectOptions.Clear();
                GameOptions.Clear();
                pgs ??= [];
                foreach (var data in pgs)
                {
                    ProjectOptions.Add(data.Name);
                }
                if (pgs.Count >= 1)
                {
                    foreach (var item in pgs.First().Games)
                        GameOptions.Add(item.Name);
                }
            }
            catch (Exception ex)
            {
                GlobalMessage.Instance.ShowError($"数据加载错误：{ex.Message}");
            }
            finally
            { IsLoading = false; }
        }

        private async Task LoadFromApi()
        {
            var validationResults = QueryDto.Validate(new ValidationContext(QueryDto)).ToList();
            QueryDto.PageIndex = PageIndex;
            QueryDto.PageSize = PageSize;
            QueryDto.ProjectName = SelectedProject;
            QueryDto.GameName = SelectedGame;
            var res = await _service.GetPageAsync(QueryDto);
            if (res.StatusCode != 200)
            {
                GlobalMessage.Instance.ShowError(JSON.Serialize(res.Errors));
                return;
            }
            PageSize = res.Data.PageSize;
            TotalPages = res.Data.TotalPages;
            TotalCount = res.Data.TotalCount;
            HasNextPages = res.Data.HasNextPages;
            HasPrevPages = res.Data.HasPrevPages;
            PageIndex = res.Data.PageIndex;
            RechargeRecords.Clear();
            if (res.Data.Items == null)
                return;
            foreach (var rr in res.Data.Items)
            {
                RechargeRecords.Add(rr);
            }
            await GetStatisticsAsync();
        }

        private async Task GetStatisticsAsync()
        {
            var res = await _service.GetSTAsync(QueryDto);
            if (res.StatusCode != 200)
            {
                GlobalMessage.Instance.ShowError(JSON.Serialize(res.Errors));
                return;
            }
            STString = $"【{DateTime.Parse(QueryDto.StartTime).ToStringFormat()}至{DateTime.Parse(QueryDto.EndTime24).ToStringFormat()}】";
            STAll = res.Data[0];
            STToDay = res.Data[1];
        }
    }
}